home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-03 / qbnws102.zip / SSEARCH.ZIP / SSEARCH.ASM next >
Assembly Source File  |  1990-02-02  |  3KB  |  73 lines

  1.  
  2. ;------ SearchString - reveals Microsoft QuickBASIC's INSTR algorithm
  3.  
  4. ;syntax:  Found = SearchString%(BYVAL StartChar%, Source$, Search$)
  5. ;
  6. ; where:
  7. ;
  8. ;   StartChar% specifies where in the source string searching is to begin,
  9. ;   Source$ is the string being searched, and Search$ is the string to find.
  10. ;   Found then receives the position in Source$ where Search$ is found
  11. ;   (1-based), or zero if there was no match.
  12. .Model Medium,Basic
  13.  
  14. .Code
  15.  
  16. SearchString Proc Uses SI DI, Start:Word, Source:Word, Search:Word
  17.  
  18.     Cld                   ;insure that string instructions are forward
  19.     Push DS               ;assign ES=DS
  20.     Pop  ES
  21.     Mov  AX,Start         ;put Start% into AX
  22.  
  23.     Mov  SI,Search        ;get the address for the Search$ descriptor
  24.     Mov  DX,[SI]          ;put its length into DX
  25.     Mov  SI,[SI+02]       ;and its address into SI
  26.     Dec  DX               ;we'll handle the first character using Scasb
  27.     Js   Exit             ;they slipped us a null string, so return Start%
  28.  
  29.     Mov  DI,Source        ;get the address for the Source$ descriptor
  30.     Mov  CX,[DI]          ;put its length into CX
  31.     Mov  DI,[DI+02]       ;and its address into DI
  32.     Mov  BX,DI            ;save that in BX to see how far we searched later
  33.  
  34.     Dec  AX               ;adjust Start% so 1st character = 0 offset
  35.     Js   NotFound         ;Start% was zero or negative, get out and return 0
  36.     Add  DI,AX            ;advance Start% bytes into the string
  37.     Sub  CX,AX            ;and consider that many fewer characters to search
  38.     Jbe  NotFound         ;they tried to start past the end
  39.  
  40.     Lodsb                 ;get and skip over the first character in Search$
  41.  
  42. Scan:
  43.     Repne Scasb           ;find the first character in Source$ that matches
  44.     Jne  NotFound         ;if it's not there, the complete string isn't either
  45.     Cmp  CX,DX            ;are we less than LEN(Search$) bytes from the end?
  46.     Jb   NotFound         ;yes, so there's no point in looking further
  47.     Or   DX,DX            ;was the string only one character long?
  48.     Jz   Found            ;yes, so this must be it
  49.  
  50.     Push SI               ;save the current scanning context
  51.     Push DI
  52.     Push CX
  53.     Mov  CX,DX            ;search LEN(Search$) characters
  54.     Repe Cmpsb            ;compare the two strings
  55.     Pop  CX               ;restore the context in case we have to scan again
  56.     Pop  DI
  57.     Pop  SI
  58.     Jne  Scan             ;we didn't find it, keep trying
  59.  
  60. Found:                    ;we found a match
  61.     Sub  DI,BX            ;calculate how far into the string we found a match
  62.     Mov  AX,DI            ;leave the result in AX for the function output
  63.  
  64. Exit:
  65.     Ret                   ;return to caller
  66.  
  67. NotFound:
  68.     Xor  AX,AX            ;return zero to show we didn't find it
  69.     Jmp  Short Exit       ;and exit
  70.  
  71. SearchString Endp
  72. End
  73.